package web;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import ctrl.Control;
import intf.RunOSXcmd;

public class ZipUtility {
	
	static Control gui;

	public ZipUtility (Control g) {
		gui = g;
	}
	
	public static final int zipDirectory(File directory, File zip, ArrayList<String> elements)
			throws IOException {
		
		File[] files = directory.listFiles();

		int returnCode = 0;

		String OS = System.getProperty("os.name").toLowerCase();
		
		ZipOutputStream zos = null;
		if (OS.indexOf("windows") >= 0)
			 zos = new ZipOutputStream(new FileOutputStream(zip));

		for (int i = 0, n = files.length; i < n; i++){
			if(files[i].isDirectory() && elements.contains(files[i].getName())){
				System.out.println("@ZipUtility - Attempting to zip " + files[i].getName());
				
				if (OS.indexOf("mac") >= 0) {

					String cmd = "mv cache/" + files[i].getName() + " .";
					System.out.println("sending: "+ cmd);
					returnCode = RunOSXcmd.run(cmd);

					if (returnCode == 0){
						cmd = "zip -rq " + zip.getName() + " " + files[i].getName();
						System.out.println("sending: "+ cmd);
						returnCode = RunOSXcmd.run(cmd);
					}
					
					cmd = "mv " + files[i].getName() + " cache/.";
					System.out.println("sending: "+ cmd);
					returnCode = RunOSXcmd.run(cmd);
					
				}
				else if (OS.indexOf("windows") >= 0) {
					zip(files[i], directory, zos);
				}
				else if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0
						|| OS.indexOf("aix") > 0) {
					System.out.println("@zipDirectory: Needs implementation for current OS.");
					gui.println("System Error::Current OS not supported for syncing web files.");
					returnCode = -1;
				}
				else {
					System.out.println("@zipDirectory: Needs implementation for current OS.");
					gui.println("System Error::Current OS not supported for syncing web files.");
					returnCode = -1;
				}
			} //else ignore other files 
		}
		
		if (OS.indexOf("windows") >= 0)
			zos.close();

			return returnCode;
	}

	//directory is the directory to zip
	private static final void zip(File directory, File base, ZipOutputStream zos) throws IOException {
		
		File[] files = directory.listFiles();
		
		System.out.println("@zip. Zipping " + Integer.toString(files.length));
		//System.out.println("@zip. Zipping " + files[i].getName());

		byte[] buffer = new byte[8192];
		int read = 0;
		for (int i = 0, n = files.length; i < n; i++) {
			if (files[i].isDirectory()) {
				zip(files[i], base, zos);
			} else {
				FileInputStream in = new FileInputStream(files[i]);
				ZipEntry entry = new ZipEntry(files[i].getPath().substring(
						base.getPath().length() + 1));
				zos.putNextEntry(entry);
				while (-1 != (read = in.read(buffer))) {
					zos.write(buffer, 0, read);
				}
				in.close();
			}
		}
	}

	public static final void unzip(File zip, File extractTo) throws IOException {
		ZipFile archive = new ZipFile(zip);
		Enumeration e = archive.entries();
		while (e.hasMoreElements()) {
			ZipEntry entry = (ZipEntry) e.nextElement();
			File file = new File(extractTo, entry.getName());
			if (entry.isDirectory() && !file.exists()) {
				file.mkdirs();
			} else {
				if (!file.getParentFile().exists()) {
					file.getParentFile().mkdirs();
				}

				InputStream in = archive.getInputStream(entry);
				BufferedOutputStream out = new BufferedOutputStream(
						new FileOutputStream(file));

				byte[] buffer = new byte[8192];
				int read;

				while (-1 != (read = in.read(buffer))) {
					out.write(buffer, 0, read);
				}

				in.close();
				out.close();
			}
		}
		archive.close();
	}
}
